import numpy as np
import urllib.request

url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
response = urllib.request.urlopen(url)
data = response.read().decode('utf-8')

lines = data.strip().split('\n')
iris_data = []
for line in lines:
    if line.strip():
        parts = line.split(',')
        if len(parts) == 5:
            features = [float(x) for x in parts[:4]]
            label_str = parts[4].strip()

            if label_str == 'Iris-setosa':
                label = 0
            elif label_str == 'Iris-versicolor':
                label = 1
            else:
                label = 2
            iris_data.append(features + [label])

iris_data = np.array(iris_data)
X = iris_data[:, :4]
y = iris_data[:, 4]

print("Iris数据集:")
print(f"样本数: {X.shape[0]}, 特征数: {X.shape[1]}")
print(f"类别0: {np.sum(y == 0)}, 类别1: {np.sum(y == 1)}, 类别2: {np.sum(y == 2)}")

class SimpleKNN:
    def __init__(self, k=3):
        self.k = k

    def fit(self, X, y):
        self.X_train = X
        self.y_train = y

    def predict(self, X_test):
        predictions = []
        for x in X_test:
            distances = np.sqrt(np.sum((self.X_train - x) ** 2, axis=1))
            k_indices = np.argsort(distances)[:self.k]
            k_nearest = self.y_train[k_indices]
            prediction = np.bincount(k_nearest.astype(int)).argmax()
            predictions.append(prediction)
        return np.array(predictions)

split = int(0.7 * len(X))
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]

knn = SimpleKNN(k=5)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)

accuracy = np.sum(y_pred == y_test) / len(y_test)
print(f"\nKNN准确率: {accuracy:.2%}")

print("\n预测结果（前10个）:")
for i in range(min(10, len(y_test))):
    correct = "正确" if y_test[i] == y_pred[i] else "错误"
    print(f"真实: {int(y_test[i])}, 预测: {int(y_pred[i])}, {correct}")